package com.file.manage.domain.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.file.manage.domain.request.UpdateUserInfoRequest;
import com.file.manage.domain.param.UserQueryParam;
import com.file.manage.infrastructure.base.Pager;
import com.file.manage.infrastructure.base.dto.query.PageQuery;
import com.file.manage.infrastructure.dao.UserFileMappingDao;
import com.file.manage.infrastructure.dao.impl.UserDaoImpl;
import com.file.manage.infrastructure.base.service.impl.BaseServiceImpl;
import com.file.manage.infrastructure.config.CurrentUserCache;
import com.file.manage.domain.data.UserInfo;
import com.file.manage.domain.entity.User;
import com.file.manage.domain.entity.convertor.UserConvertor;
import com.file.manage.domain.request.RegisterRequest;
import com.file.manage.domain.request.UpdatePasswordRequest;
import com.file.manage.domain.service.UserService;
import com.file.manage.infrastructure.exception.ServiceException;
import com.file.manage.infrastructure.utils.IdGenerator;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @since 2025-05-22
 */
@Service
public class UserServiceImpl extends BaseServiceImpl<UserDaoImpl, User> implements UserService {
    @Resource
    private UserFileMappingDao userFileMappingDao;

    @Override
    public void register(RegisterRequest registerRequest) {
        Assert.isNull(this.baseDao.getOne(new QueryWrapper<User>().lambda().eq(User::getAccount, registerRequest.getAccount())), "账号已存在");
        User user = new User();
        user.setId(IdGenerator.identity());
        user.setName(registerRequest.getName());
        user.setAccount(registerRequest.getAccount());
        user.setPassword(registerRequest.getPassword());
        user.setRole(registerRequest.getRole());
        user.setCreatedTime(new Date());
        user.setCreatedBy(user.getId());
        this.save(user);
    }

    @Override
    public void updatePassword(UpdatePasswordRequest updatePasswordRequest) {
        User user = this.baseDao.getOne(new QueryWrapper<User>().lambda().eq(User::getAccount, updatePasswordRequest.getAccount()));
        Assert.notNull(user, "账号不存在");
        Assert.isTrue(user.getPassword().equals(updatePasswordRequest.getOldPassword()), "密码错误");
        user.setPassword(updatePasswordRequest.getNewPassword());
        user.setUpdatedTime(new Date());
        this.updateById(user);
    }

    @Override
    public String login(String account, String password) {
        if (StrUtil.isBlank(account) || StrUtil.isBlank(password)) throw new ServiceException("账号或密码不能为空");

        User user = this.baseDao.getOne(new QueryWrapper<User>().lambda().eq(User::getAccount, account).eq(User::getPassword, password));
        if (user == null) throw new ServiceException("账号或密码错误");
        StpUtil.login(user.getId());
        StpUtil.getSession().set(user.getId(), UserConvertor.INSTANCE.toUserInfo(user));
        return StpUtil.getTokenInfo().getTokenValue();
    }

    @Override
    public UserInfo getCurrentUser() {
        return CurrentUserCache.get();
    }


    @Override
    public void updateUserInfo(UpdateUserInfoRequest request) {
        User user = this.baseDao.getById(request.getId());
        Assert.notNull(user, "用户不存在");
        if (StrUtil.isNotBlank(request.getName())) user.setName(request.getName());
        if (StrUtil.isNotBlank(request.getPassword())) user.setPassword(request.getPassword());
        if (request.getRole() != null) user.setRole(request.getRole());
        this.updateById(user);
        if (user.getId().equals(StpUtil.getLoginId())) {
            StpUtil.getSession().set(user.getId(), UserConvertor.INSTANCE.toUserInfo(user));
        }
    }

    @Override
    public List<UserInfo> listUserInfo(UserQueryParam param) {
        return UserConvertor.INSTANCE.toUserInfo(this.baseDao.selectUserByParam(param));
    }

    @Override
    public Pager<UserInfo> pageUserInfo(PageQuery<UserQueryParam> pageQuery) {
        Page<User> userPage = this.baseDao.pageUserByParam(new Page<>(pageQuery.getCurrent(), pageQuery.getLimit()), pageQuery.getEntity());
        return new Pager<>(userPage.getTotal(), UserConvertor.INSTANCE.toUserInfo(userPage.getRecords()));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteUser(String id) {
        this.removeById(id);
        userFileMappingDao.deleteByUserId(id);
    }

}
